package enviro;

import java.io.Serializable;
import entity.*;

/**
 * The tile class represents one unit of movement and space 
 * in a dungeon.  It can be serialized and stored in a file.
 * 
 * @author timon
 */
public class Tile implements Serializable, Environment {
	
    // <editor-fold defaultstate="collapsed" desc="Member Variables">
    
	private String imagepath; // The image which will be painted onto the tile.
        
        // DungeonEntity belonging to this tile (if any)       
        private DungeonEntity dunEntity = new DungeonEntity();
        
        // Defines the environment type
        private final EnviroType ENVIRO_TYPE = EnviroType.TILE;

    // </editor-fold>
        
    // <editor-fold defaultstate="collapsed" desc="Constructor(s)">
        
        /**
         * Default Constructor
         */
        public Tile() {
            
        }
        
    // </editor-fold>
        
    // <editor-fold defaultstate="collapsed" desc="API">   
    
        
        /**
         * Get a Dungeon Entity based on its position
         * 
         * 
         * @return
         *   The Entity in that position will be returned to the user. 
         */
        public DungeonEntity getDungeonEntity() {
           
            return dunEntity;
        }
        
        /**
         * Spawn a unique instance of this object and return to caller
         * 
         * This was built to help avoid problems assigning objects to array
         * (which, if I'm not mistaken, is done by reference - FORCING us
         * to deliver separate instances somehow).
         * 
         * @return 
         *   A carbon copy of this object
         */
        public Tile spawnInstance()
        {
            Tile spawnTile = new Tile();
            spawnTile.imagepath = imagepath;
            spawnTile.setDungeonEntity(dunEntity);
            
            return spawnTile;
            
        }
        
        @Override
        /**
         * Place an entity into the tile.  
         * 
         * @param position
         *   Ignored.  Passing a null value here is just fine.
         * @param entity
         *   The entity you intend to place on this tile.
         * 
         * @return
         *   Returns true on successful operation. Failure indicated by false.
         */
        public boolean placeEntity(int[][] position, Entity entity) {
            
            // Determine the class of the entity.
            Class entityType = entity.getClass();
            

            // If the entity is a DungeonEntity
            if (entityType == new DungeonEntity().getClass())
            {

                // Convert the entity into a DungeonEntity
                DungeonEntity dungeonEntity = (DungeonEntity) entity;

                // Place the entity on the board.
                return placeEntity(dungeonEntity);
            }
            
            // Return false if the entity type was not recognized.
            return false;
            
        }
        
        /**
         * Place a DungeonEntity into the tile.  
         * 
         * @param entity
         *   The entity you intend to place on this tile.
         * 
         * @return
         *   Returns true on successful operation. Failure indicated by false.
         */
        public boolean placeEntity(DungeonEntity entity) { 
            
                return setDungeonEntity(entity);
        }
        
        /**
	 * Standard Get / Set Methods
	 */
	public String getImagepath() {
		return imagepath;
	}
	public void setImagepath(String imagepath) {
		this.imagepath = imagepath;
	}
        
    // </editor-fold>
        
    // <editor-fold defaultstate="collapsed" desc="Private Utilities">    
        
        /**
         * Set a Dungeon Entity
         * 
         * You can use this method to assign an entity to a slot on the tile
         * (for example, a wall on the north edge)
         * 
         * Note that whatever you put in this slot will replace it's 
         * prior occupant.
         * 
         * @param entity
         *   This is the entity you are inserting
         */
        private boolean setDungeonEntity(DungeonEntity dungeonEntity) {
            
            try {
                
                if (!dungeonEntity.isFriendlyWith(this.ENVIRO_TYPE))
                    throw new RH_MisplacedEntity();
                
                this.dunEntity = dungeonEntity;
                
            }
            catch (RH_MisplacedEntity ex) {
            
            /**
             * @todo - Build the catch block for misplaced DungeonEntities
             */
            
            }
        
            // Confirm the operation by returning true.
            return true;
         }
        
    // </editor-fold>
        
        
        
}
